✅状態遷移再設計 (scrapbox-select-suggestion)
from 選択範囲に似ているリンクを入力補完するUserScript
reducerにページ本文や選択範囲変更時の状態遷移処理まで含めた
takker99/emoji-completionで試すevent loop設計にあるようなループをすべて単体テストできるようになった
修正が期待できるバグ
✅キーを打つと、補完の有効化と無効化が1キーずつ繰り返される
scrapbox.Page.linesからリンク検知するよう変更した
あれ?これ以前話題にでたような……
また強い既視感が……
でもタイミングはずれそう
もしずれるようなら、debounceを挟もう
まとめてやったこと
カーソルを含むリンクを、scrapbox.Page.linesから探索する
DOM経由よりバグが少ない
状況によって微妙に構造が変わってしまう
場合分けしてコードを書くのが面倒
単体テストできる
domの場合だと、UserScriptとして読み込んで実際に使ってみてからでないとバグを発見できない
状態遷移図を書き出すつもりだったが、またメモを残さずに頭の中でcodingしてしまった
悪癖だ
少し書いたログは、選択範囲に似ているリンクを入力補完するUserScriptの開発ログ兼作業ログに転記しよう
2023-03-23
18:25:31 補完確定処理がおかしい
https://gyazo.com/27b39bbcac235f11c0c36287220ab14d
テスト中に気づかなかった……
確定処理はこれ
https://code2svg.vercel.app/svg/L127-149/https://raw.githubusercontent.com/takker99/scrapbox-select-suggestion/0.8.0/useLifecycle.ts#.svg https://github.com/takker99/scrapbox-select-suggestion/blob/0.8.0/useLifecycle.ts#L127-L149
break pointを仕掛けて調べる
https://gyazo.com/726eaf4ea0cb1d8146294079f2f69dd0
どうやらupdatorの処理を間違えているようだ
dを_に変換する関数
updatorにはCompletion.tsxのconfirmが代入されている
https://code2svg.vercel.app/svg/L77-87,blanks=1/https://raw.githubusercontent.com/takker99/scrapbox-select-suggestion/0.8.0/Completion.tsx#.svg https://github.com/takker99/scrapbox-select-suggestion/blob/0.8.0/Completion.tsx#L77-L87
わかった。queryは[]を抜いてしまっているから、[]分文字数を足さないと行けなかったんだ
queryから[]取るのやめようかな……紛らわしいし。
この紛らわしさが原因で✅選択範囲補完でリンクがずれて書き込まれる (scrapbox-select-suggestion)が起きたので止めたtakker.icon
18:43:19 治った
https://gyazo.com/8d65b970be63d3e8d986b54475aeaf62
18:12:50 merged
16:11:09 PR branchをbuildして動作確認する
17:56:45 windowの位置がずれてしまっているのを直す
position.charではなくstartを使う
18:07:55 直した
https://gyazo.com/77b57aac1788a2ec05f51f3143bcefb1
17:34:53 ↓のuseEffect()が大量にcallされてた
https://code2svg.vercel.app/svg/L65-74/https://raw.githubusercontent.com/takker99/scrapbox-select-suggestion/78d9067931ca56db839696338b9a780b551e05a5/useLifecycle.ts#.svg https://github.com/takker99/scrapbox-select-suggestion/blob/78d9067931ca56db839696338b9a780b551e05a5/useLifecycle.ts#L65-L74
selectionがuseSelectionが実行されるたびに再生成されていたのが原因
selection.rangeを監視するように直した
16:51:09 windowがちらつく
右下のdebug用表示を見ると、completionがそれ以外のmodeに僅かな間だけ切り替わっているのがわかる
https://gyazo.com/68f9a1ae449a41404df7f96e1435df2b
✅キーを打つと、補完の有効化と無効化が1キーずつ繰り返されると同じ原因だろうな
debounceしよう
このケースでは、必ずcursor:changed→lines:changedの順に呼び出されることが分かっている。
cursor:changedの次にlines:changedが呼び出されたときのみ、cursor:changedを省略するようにしよう
いや、cursor:changedだけdebounceしてもいいか
ほかはdebounceなしに実行する
いや、scrapbox.Page.linesを高頻度で呼び出したくないから、debounceは仕掛けておこう
requestAnimationFrame()でdebounceする
cf. ✅scrapbox.Page.linesをcacheして使う
17:55:59 治った
最終的に、setTimeout()でdebounceした
待ち時間を動的に変えたかったので
これで✅キーを打つと、補完の有効化と無効化が1キーずつ繰り返されるは解決した
https://gyazo.com/64dd21ef10e387a18ba451855f646f74
16:23:27 なぜかdisplay: noneになってる
表示制御は<App />でやるので、<Completion />で制御する必要はない
コード削除しそこねてたか。消そう
候補がなかったときに非表示にするロジックが暴走している
code2svg
https://code2svg.vercel.app/svg/L174-182,blanks=1/https://raw.githubusercontent.com/takker99/scrapbox-select-suggestion/78d9067931ca56db839696338b9a780b551e05a5/Completion.tsx#.svg https://github.com/takker99/scrapbox-select-suggestion/blob/78d9067931ca56db839696338b9a780b551e05a5/Completion.tsx#L174-L182
candidatesPropsはrenderされていたので、topとleftが取得できなくなっているみたい
16:49:57 useRef()のref.currentの更新をuseEffect()に入れていなかったのが原因
直した
状態を表示するdebug codeはこんな感じのを使った
code:ts
const { render } = useMemo(() => useStatusBar(), []);
useEffect(() => {
render({
type: "text",
text: `${state.type}${
state.position ? : ${state.position.line}, ${state.position.char} : ""
}`,
});
}, state.type, state.position?.line, state.position?.char);
16:09:58 単体テスト作成完了
大体はカバーできたはず
まだ抜けはありそうだが……
場合分けが多くて、書くのが大変だった
PRを作った
14:20:05 crawlLink()にバグが有ったので修正中
単体テスト項目を増やした
どうやらindentの文字数を無視してしまっているらしい
13:17:09 復帰
11:52:34 SelectionとCursorまわりの型定義修正
12:54:06 修正終了
けっこうかかった
Pageの型定義は、真面目にやっても現状メリットがないので、適当に済ませた
13:07:09 released
10:46:01 ✅ScrapboxのBaseStoreで継承先classを使えるよう型定義を変えるを先にやる
10:03:26 テスト用行データをjsonに切り出し中
09:54:42 作業開始
#2023-03-24 14:20:54
#2023-03-23 16:12:01
#2023-03-21 20:33:25
#2023-03-18 21:33:11
#2023-03-17 23:10:03